package com.dh.blog.handler;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
import java.util.UUID;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Repository;
import com.ewei.web.common.exception.MessageRuntimeException;
import com.ewei.web.common.utils.FileToolsBar;
import com.ewei.web.common.utils.PathUtils;
/**
 * 
 * @author David
 *
 */
@Repository
public class DefaultSaveFileHandler implements SaveFileHandler{
//	private static final Logger logger = LogManager.getLogger(DefaultSaveFileHandler.class);
//	protected static final String DEFAULT_POSTFIX = ".dat";
	@Resource
	private Properties config;
	private String rootDir;
	@PostConstruct
	public String rootDir(){
		if(null == rootDir){
			if(null != config){
				Object param = config.get("file_disk_dir");
				if(null != param){
					rootDir = String.valueOf(param);
				}
			}
		}
		return rootDir;
	}
	@Override
	public String saveByDir(InputStream in, String dir) {
		return saveByDir(in, dir, null);
	}
	@Override
	public String saveByDir(InputStream in, String dir, String name) {
		if(null!=rootDir()){
			String path = resolvePath(dir, name);
			saveByAbsolute(in, rootDir()+path);
			return path;
		}else{
			throw new MessageRuntimeException("rootDir is null!");
		}
	}
	@Override
	public String saveByDate(InputStream in, Date date) {
		return saveByDate(in,date,null);
	}
	@Override
	public String saveByDate(InputStream in, Date date, String name) {
		if(null!=rootDir()){
			String path = resolvePath(date, name);
			saveByAbsolute(in, rootDir()+path);
			return path;
		}else{
			throw new MessageRuntimeException("rootDir is null!");
		}
	}
	@Override
	public String saveByRelative(InputStream in,String relativePath){
		if(null!=rootDir()){
			saveByAbsolute(in, rootDir()+relativePath);
			return relativePath;
		}else{
			throw new MessageRuntimeException("rootDir is null!");
		}
	}
	protected void saveByAbsolute(InputStream in ,String absolutePath){
		File file = new File(absolutePath);
		boolean deleted = true;
		if(file.exists()){
			deleted= file.delete();
		}else{
			file.getParentFile().mkdirs();
		}
		if(null == in){
			newFile(file);
		}else if(deleted){
			try {
				FileToolsBar.uploadsf(in, absolutePath, -1);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}else{
			throw new MessageRuntimeException("the existed file is locked!");
		}
	}
	protected String resolvePath(String dir,String name){
		name = resolveName(name);
		String formatDir = "";
		if(null != dir){
			formatDir = PathUtils.format(dir);
		}
		StringBuilder result = new StringBuilder();
		if(!rootDir().endsWith("/") && !formatDir.startsWith("/")){
			result.append("/")
			.append(formatDir).append("/")
			.append(name);
			return result.toString();
		}else{
			return PathUtils.format(result.append(formatDir)
					.append("/").append(name).toString());
		}
	}
	protected String resolvePath(Date date,String name){
		name = resolveName(name);
		if(null == date){
			date = Calendar.getInstance().getTime();
		}
		SimpleDateFormat format =  new SimpleDateFormat("yyyy-MM-dd");
		String formatDate = format.format(date);
		formatDate = formatDate.replaceAll("-","/");
		StringBuilder result = new StringBuilder();
		if(!rootDir().endsWith("/")){
			result.append("/")
					.append(formatDate).append("/")
					.append(name);
			return	result.toString();
		}else{
			return result.append(formatDate)
					.append("/").append(name).toString();
		}
	}
	private String resolveName(String name){
		long current0 = System.currentTimeMillis();
		if(null == name || "".equals(name.trim())){
//			name = UUID.randomUUID().toString().replace("-","");对UUID方法持有保留意见，效率太低
			try {
				name = "";
				MessageDigest digest = MessageDigest.getInstance("MD5");//用MD5是为了它对原值敏感的特性和固定长度
				digest.digest();//reset
				int hash = Thread.currentThread().hashCode();
				String str =String.valueOf(current0)+String.valueOf(hash);//将线程hash和当前时间戳结合
				for(byte b:digest.digest(str.getBytes())){
					int a= b&0xff;
					if(a<16){
						a+=16;
					}
					name=name+Integer.toHexString(a);
				}
			} catch (NoSuchAlgorithmException e) {
				throw new MessageRuntimeException(e);
			}
		}else{
			if(name.contains("/")){
				throw new MessageRuntimeException("the name is illegal!");
			}
		}
		return name;
	}
	private void newFile(File file){
		if(!file.exists()){
			try {
				file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	@Override
	public void remove(String relativePath) {
		FileToolsBar.deleteFileOrDirectory
		(rootDir()+relativePath);
	}
	@Override
	public void transfer(String path0, String path1) {
		try {
			FileUtils.moveFile(new File(rootDir()+path0),
					new File(rootDir()+path1));
		} catch (IOException e) {
			throw new MessageRuntimeException(e);
		}
	}
}
